﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using ERPStore.Extensions;

using CloudSoft.Extensions;

namespace ERPStore.Exporter.Providers
{
	public abstract class ExportBase : IDisposable, ERPStore.Exporter.Providers.IExport
	{
		private ERPStore.Models.LeadSourceBase m_LeadSource;

		public ExportBase()
		{
			this.CryptoService = GlobalConfiguration.Configuration.DependencyResolver.GetService<ERPStore.Services.CryptoService>();
			this.RegistrationService = GlobalConfiguration.Configuration.DependencyResolver.GetService<ERPStore.Services.ILeadSourceRegistrationService>();
			this.ProductIdList = new List<int>();
		}

		protected ERPStore.Services.CryptoService CryptoService { get; private set; }
		protected ERPStore.Services.ILeadSourceRegistrationService RegistrationService { get; private set; }

		public virtual ERPStore.Models.LeadSourceBase LeadSource
		{
			get
			{
				if (m_LeadSource != null)
				{
					return m_LeadSource;
				}
				m_LeadSource = RegistrationService.List.FirstOrDefault(i => i.Id.Equals(LeadSourceId));
				return m_LeadSource;
			}
		}

		private Models.Settings m_Settings;
		public virtual Models.Settings Settings 
		{
			get
			{
				if (m_Settings != null)
				{
					return m_Settings;
				}
				var path = Configuration.ConfigurationSettings.AppSettings["exportPath"];
				var configFileName = string.Format("{0}.config", System.IO.Path.Combine(path, Name));
				if (System.IO.File.Exists(configFileName))
				{
					var serializer = new System.Xml.Serialization.XmlSerializer(typeof(Models.Settings));
					using (var fs = System.IO.File.OpenRead(configFileName))
					{
						try
						{
							m_Settings = (Models.Settings)serializer.Deserialize(fs);
							fs.Flush();
						}
						catch(Exception ex)
						{
							var logger = GlobalConfiguration.Configuration.DependencyResolver.GetService<ERPStore.Logging.ILogger>();
							logger.Error(ex);
						}
					}
				}
				else
				{
					m_Settings = new Models.Settings();
					InitializeSettings(m_Settings);
				}
				return m_Settings;
			}
		}

		public abstract string Name { get; }
		public virtual List<int> BanishedProductIdList { get; set; }
		public virtual List<int> ProductIdList { get; set; }
		public abstract string LeadSourceId { get; }
		public virtual void InitializeSettings(Models.Settings settings) { }

		public abstract void CreateDocument();
		public abstract void AddElementToDocument(ERPStore.Models.Product product, ERPStore.Models.ProductStockInfo stockInfo);
		public abstract void SaveDocument();
		public virtual void SaveSettings()
		{
			var path = Configuration.ConfigurationSettings.AppSettings["exportPath"];
			var configFileName = string.Format("{0}.config", System.IO.Path.Combine(path, Name));
			System.IO.File.WriteAllText(configFileName, this.Settings.SerializeToXml());
		}

		protected virtual string BuildEncryptedProductUrl(ERPStore.Models.LeadSourceBase leadSource, ERPStore.Models.Product product)
		{
			var tk = new Models.TrackKey();
			tk.Date = string.Format("{0:yyMMdd}", DateTime.Now);
			tk.Medium = leadSource.Medium;
			tk.ProductCode = product.EncodedCode();
			tk.SourceId = leadSource.Id;
			tk.SourceName = leadSource.TrackSourceId.ToLower();
			var key = CryptoService.Encrypt(tk);

			var result = string.Format("http://{0}/cp/trk/{1}"
				, GlobalConfiguration.Configuration.Settings.DefaultUrl
				, key);

			return result;
		}

		protected virtual string GetDeepCategoryName(ERPStore.Models.Product product)
		{
			var path = new List<string>();
			var c = product.Category;
			if (c != null)
			{
				return c.Name;
			}
			//while (true)
			//{
			//    if (c != null)
			//    {
			//        path.Add(c.Name);
			//    }
			//    else
			//    {
			//        break;
			//    }
			//    c = c.Parent;
			//}
			//if (path.IsNullOrEmpty())
			//{
			//    return string.Empty;
			//}

			//path.Reverse();
			//return path.JoinString(" > ");
			return string.Empty;
		}

		protected string QuoteString(string input)
		{
			if (input == null)
			{
				return string.Empty;
			}
			var result = input.Replace("\"", "\"\"");

			return result;
		}

		protected string CapitalizeWords(string phrase)
		{
			if (phrase == null)
			{
				return null;
			}
			var upperCount = phrase.Count(c => Char.IsUpper(c));
			if (upperCount < 10)
			{
				return phrase;
			}

			var words = phrase.ToLower().ToWordList();
			string result = null;
			foreach (var word in words)
			{
				var f = word[0];
				var capitalizedWord = word;
				if (char.IsLetter(f))
				{
					capitalizedWord = char.ToUpper(f) + word.Substring(1);
				}
				result += capitalizedWord + " ";
			}

			return result.Trim();
		}


		#region IDisposable Members

		public abstract void Dispose();

		#endregion

		protected string ToCurrency(decimal value)
		{
			return ToCurrency(value, false);
		}

		protected string ToCurrency(decimal value, bool hideSymbol)
		{
			var result = ToCurrencyInternal(value, hideSymbol);
			return System.Web.HttpUtility.HtmlDecode(result);
		}

		private string ToCurrencyInternal(decimal value, bool hideSymbol)
		{
			string symbol = ERPStore.GlobalConfiguration.Configuration.Settings.Format.CurrencySymbol;
			if (hideSymbol)
			{
				symbol = string.Empty;
			}
			var pattern = GetPattern(value);
			return string.Format(pattern, value, symbol);
		}

		private string GetPattern(decimal value)
		{
			var pattern = ERPStore.GlobalConfiguration.Configuration.Settings.Format.NormalPricePattern + "{1}";
			if (value < ERPStore.GlobalConfiguration.Configuration.Settings.Format.SmallPriceLimit)
			{
				pattern = ERPStore.GlobalConfiguration.Configuration.Settings.Format.SmallPricePattern + "{1}";
			}
			return pattern;
		}


	}
}
